package com.cyl.h5.service;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import io.swagger.annotations.ApiModelProperty;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.cyl.h5.config.SecurityUtil;
import com.cyl.h5.domain.dto.OrderProductListDTO;
import com.cyl.h5.domain.dto.PayNotifyMessageDTO;
import com.cyl.h5.domain.form.*;
import com.cyl.h5.domain.vo.*;
import com.cyl.manager.act.domain.entity.CouponCategory;
import com.cyl.manager.act.domain.entity.MemberCoupon;
import com.cyl.manager.act.mapper.CouponCategoryMapper;
import com.cyl.manager.act.service.CouponCategoryService;
import com.cyl.manager.act.service.IntegralHistoryService;
import com.cyl.manager.act.service.MemberCouponService;
import com.cyl.manager.oms.convert.AftersaleItemConvert;
import com.cyl.manager.oms.convert.OrderItemConvert;
import com.cyl.manager.oms.domain.entity.*;
import com.cyl.manager.oms.domain.form.ManagerOrderQueryForm;
import com.cyl.manager.oms.domain.vo.ManagerOrderVO;
import com.cyl.manager.oms.mapper.*;
import com.cyl.manager.oms.service.OrderItemService;
import com.cyl.manager.oms.service.OrderOperateHistoryService;
import com.cyl.manager.pms.domain.entity.Product;
import com.cyl.manager.pms.domain.entity.Sku;
import com.cyl.manager.pms.domain.vo.DyFlq;
import com.cyl.manager.pms.domain.vo.DyFlqSy;
import com.cyl.manager.pms.mapper.ProductMapper;
import com.cyl.manager.pms.mapper.SkuMapper;
import com.cyl.manager.ums.domain.entity.Member;
import com.cyl.manager.ums.domain.entity.MemberAddress;
import com.cyl.manager.ums.domain.entity.MemberCart;
import com.cyl.manager.ums.domain.entity.MemberWechat;
import com.cyl.manager.ums.mapper.MemberAddressMapper;
import com.cyl.manager.ums.mapper.MemberCartMapper;
import com.cyl.manager.ums.mapper.MemberWechatMapper;
import com.cyl.manager.ums.service.MemberAccountService;
import com.cyl.wechat.WechatPayData;
import com.cyl.wechat.WechatPayService;
import com.cyl.wechat.WechatPayUtil;
import com.cyl.yeepay.setvice.YeePayService;
import com.cyl.yeepay.vo.PayNotifyRetVo;
import com.github.pagehelper.PageHelper;
import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.core.redis.RedisService;
import com.ruoyi.common.enums.AftersaleStatus;
import com.ruoyi.common.enums.OrderRefundStatus;
import com.ruoyi.common.enums.OrderStatus;
import com.ruoyi.common.utils.AesCryptoUtils;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.IDGenerator;
import com.ruoyi.common.utils.PhoneUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.framework.config.LocalDataUtil;
import com.ruoyi.system.service.ISysDeptService;
import com.wechat.pay.java.service.partnerpayments.jsapi.model.Transaction;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.springframework.beans.factory.annotation.Value;

@Service
@Slf4j
public class H5OrderService {

	@Value("${aes.key}")
    private String aesKey;
	
    @Autowired
    private MemberAddressMapper memberAddressMapper;

    @Autowired
    private SkuMapper skuMapper;

    @Autowired
    private ProductMapper productMapper;

    
    
    @Autowired
    private MemberCartMapper memberCartMapper;
    @Autowired
    private CouponCategoryMapper couponCategoryMapper;
    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private OrderItemMapper orderItemMapper;

    @Autowired
    private OrderOperateHistoryMapper orderOperateHistoryMapper;

    @Autowired
    private OrderItemService orderItemService;

    @Autowired
    private OrderOperateHistoryService orderOperateHistoryService;

    @Autowired(required = false)
    private YeePayService yeePayService;
    

    @Autowired
    private MemberWechatMapper memberWechatMapper;

    @Autowired
    private WechatPaymentHistoryMapper wechatPaymentHistoryMapper;

    @Autowired
    private RedisService redisService;

    @Autowired
    private AftersaleMapper aftersaleMapper;

    @Autowired
    private AftersaleItemMapper aftersaleItemMapper;

    @Autowired
    private AftersaleItemConvert aftersaleItemConvert;

    @Autowired
    private OrderItemConvert orderItemConvert;

    @Autowired
    private IntegralHistoryService integralHistoryService;

    @Autowired
    private MemberCouponService memberCouponService;
    
    @Autowired
    private ISysDeptService deptService;
    @Autowired
    private MemberAccountService memberAccountService;
    
    
    @Autowired
    private CouponCategoryService couponCategoryService;
    
    private final static BigDecimal payRate = new BigDecimal("0.006");//费率

    private BigDecimal getFeeAmount(BigDecimal payAmount){
    	if(payAmount==null) {
            throw new RuntimeException("支付金额不能为空");
    	}
    	if (payAmount.compareTo(BigDecimal.ZERO) < 0) {
            throw new RuntimeException("支付金额不能小于0");
        } 
        return payAmount.multiply(H5OrderService.payRate).setScale(2, RoundingMode.HALF_UP);
    }
 

    @Transactional
    public Long submit(OrderSubmitForm form) {
        Member member = (Member) LocalDataUtil.getVar(Constants.MEMBER_INFO);
        //只支持快递
//        Long addressId = form.getAddressId();
//        if (addressId == null) {
//            throw new RuntimeException("收获地址不能为空");
//        }
        int process = 0;//订单流程：0正常流程  1支付就待提货
        SysDept sysDept = deptService.getCacheSysDept(member.getDeptDpId());
        MemberAddress memberAddress = new MemberAddress();
        memberAddress.setName(sysDept.getLeader());
        memberAddress.setPhoneHidden(sysDept.getPhone());
        memberAddress.setPhoneEncrypted(AesCryptoUtils.encrypt(aesKey, sysDept.getPhone()));
        memberAddress.setProvince(sysDept.getProvince());
        memberAddress.setCity(sysDept.getCity());
        memberAddress.setDistrict(sysDept.getDistrict());
        memberAddress.setDetailAddress(sysDept.getAddress());
        String keyword = "";
        String productName = "";

        if (sysDept.getAddress() == null) {
            throw new RuntimeException("收货地址不能为空");
        }
        //sku不能为空
        List<OrderProductListDTO> skuList = form.getSkuList();
        if (CollectionUtil.isEmpty(skuList)) {
            throw new RuntimeException("商品SKU信息不能为空");
        }
        int skuSize = skuList.size();
        if (skuSize!=1) {
            throw new RuntimeException("不支持一单多个商品，请分批下单");
        }
        int   quantity = 0;
        //将sku信息转换为 key：skuId ，value：购买数量
        Map<Long, Integer> skuQuantityMap = skuList.stream().collect(Collectors.toMap(OrderProductListDTO::getSkuId, OrderProductListDTO::getQuantity));
        //查询所有sku信息
        Map<Long, Sku> querySkuMap = skuMapper
                .selectBatchIds(skuList.stream().map(OrderProductListDTO::getSkuId).collect(Collectors.toList()))
                .stream().collect(Collectors.toMap(Sku::getId, it -> it));
        //校验优惠券
        BigDecimal couponAmount = BigDecimal.ZERO;
//        if (form.getMemberCouponId() != null) {
//            MemberCoupon coupon = memberCouponService.selectValidCoupon(form.getMemberCouponId());
//            if (coupon == null) {
//                throw new RuntimeException("优惠券未找到");
//            }
//            //将sku转换成products
//            Map<Long, Product> products = new HashMap<>();
//            querySkuMap.forEach((k, v) -> {
//                Integer count = skuQuantityMap.get(k);
//                Long productId = v.getProductId();
//                Product product;
//                BigDecimal amount = v.getPrice().multiply(BigDecimal.valueOf(count));
//                if (products.containsKey(k)) {
//                    product = products.get(k);
//                    product.setPrice(amount.add(product.getPrice()));
//                } else {
//                    product = new Product();
//                    product.setId(productId);
//                    product.setPrice(amount);
//                }
//                products.put(k, product);
//            });
//            if (!memberCouponService.judgeCouponCanUse(coupon, products.values())) {
//                throw new RuntimeException("优惠券未达到使用条件");
//            }
//            couponAmount = coupon.getCouponAmount();
//        }
        //计算商品总额、订单总额（订单总金额=商品总金额，因为暂时没有运费等概念）
        BigDecimal productTotalAmount = BigDecimal.ZERO;
        BigDecimal orderTotalAmount = BigDecimal.ZERO;
        BigDecimal ordercgprice = BigDecimal.ZERO;

        BigDecimal orderdpjsprice = BigDecimal.ZERO;
        String cplx = "1";//默认正常商品
        Long dhCouponCategoryId = null;//兑换的福利券分类id
        Long dhCouponCategoryNum = null;//兑换福利券的数量
        Long brandId = 0L;// 表示没有供应商
        BigDecimal dhJssl = null;//兑换积分数量
        LocalDateTime ktkTime = null;

        Product product = null;
        String merchantNote = null;
        for (OrderProductListDTO dto : skuList) {
            if (!querySkuMap.containsKey(dto.getSkuId())) {
                throw new RuntimeException("商品SKU不存在");
            }
            Sku sku = querySkuMap.get(dto.getSkuId());
            product = productMapper.selectById(sku.getProductId());
            if (product == null) {
                throw new RuntimeException("商品不存在");
            }
            brandId = product.getBrandId();
            ktkTime = product.getKtkTime();
            cplx = product.getCplx();
            dhCouponCategoryId = product.getDhCouponCategoryId();
            if(cplx!=null) {
            	if("2".equals(cplx)) {
              	  dhCouponCategoryNum = sku.getDhCouponCategoryNum() * dto.getQuantity().intValue(); //需要券 
              	  if(sku.getDhJssl()!=null && !sku.getDhJssl().equals(BigDecimal.ZERO)) {
                    dhJssl = sku.getDhJssl().multiply(BigDecimal.valueOf(dto.getQuantity()));
            	  }
            	}
            	if("3".equals(cplx)) {
                    dhJssl = sku.getDhJssl().multiply(BigDecimal.valueOf(dto.getQuantity()));
              	}  
            }
          

            if (Constants.PublishStatus.UNDERCARRIAGE.equals(product.getPublishStatus())) {
                throw new RuntimeException("商品" + product.getName() + "已下架");
            }
            if (sku.getStock() < skuQuantityMap.get(sku.getId())) {
                throw new RuntimeException("库存不足");
            }
            if(product.getProcess()!=null) {
            	process  = product.getProcess().intValue();
            }
            quantity = quantity + dto.getQuantity().intValue();
            keyword += product.getName()+sku.getSpData()+" ";
            productName =  product.getName()+"";
            addOrderCheck(member.getId(), product,sku, dto.getQuantity());
            productTotalAmount = productTotalAmount.add(sku.getPrice().multiply(BigDecimal.valueOf(skuQuantityMap.get(sku.getId()))));
            orderTotalAmount = orderTotalAmount.add(sku.getPrice().multiply(BigDecimal.valueOf(skuQuantityMap.get(sku.getId()))));
            BigDecimal cgprice = sku.getCgprice();
            if(cgprice==null) {
            	cgprice = BigDecimal.ZERO;
            }
            ordercgprice = ordercgprice.add(cgprice.multiply(BigDecimal.valueOf(skuQuantityMap.get(sku.getId()))));

            BigDecimal dpPrice = sku.getDpjsprice();
            if(dpPrice==null) {
            	dpPrice = BigDecimal.ZERO;
            }
            orderdpjsprice = orderdpjsprice.add(dpPrice.multiply(BigDecimal.valueOf(skuQuantityMap.get(sku.getId()))));
            

            dto.setSku(sku);
            dto.setProduct(product);
        }
        LocalDateTime optTime = LocalDateTime.now();
       
        //生成一个统一的订单号
        Long orderId = IDGenerator.generateId();
        //生产一个payId
        Long payId = orderId;
        //创建订单
        keyword = keyword +("订单id："+orderId)+("用户id："+member.getId());
        Order order = new Order();
        order.setDpjsprice(orderdpjsprice);//店铺结算金额

        order.setCplx(cplx);//产品类型  1 正常商品 2 福利券商品 3 积分商品
        order.setDhCouponCategoryId(dhCouponCategoryId);//兑换的福利券分类id
        order.setDhCouponCategoryNum(dhCouponCategoryNum);//兑换的福利券分类id
        order.setDhJssl(dhJssl);//兑换积分数量
        order.setBrandId(brandId);
        order.setKtkTime(ktkTime);
        order.setCgprice(ordercgprice);
        order.setPayId(payId);
        order.setQuantity(quantity);
        order.setId(orderId);
        order.setOrderSn(this.getOrderIdPrefix() + orderId);
        order.setMemberId(member.getId());
        order.setMemberUsername(member.getNickname());
        order.setSkuSize(skuSize);
        order.setDeptZbjId(member.getDeptZbjId());
        order.setDeptTzId(member.getDeptTzId());
        order.setDeptDpId(member.getDeptDpId());
        
        order.setSpreaduid(member.getSpreaduid());

        order.setKeyword(keyword);
        order.setPayType(Constants.PayType.WECHAT);
        order.setCouponAmount(couponAmount);
        order.setMemberCouponId(form.getMemberCouponId());
        order.setTotalAmount(orderTotalAmount);
        order.setPurchasePrice(BigDecimal.ZERO);
        order.setFreightAmount(BigDecimal.ZERO);
        order.setProcess(process);
        order.setMerchantNote(merchantNote);
        BigDecimal subtract = orderTotalAmount.subtract(couponAmount);
        order.setPayAmount(subtract.compareTo(BigDecimal.ZERO) > 0 ? subtract : BigDecimal.ZERO);
        if (order.getPayAmount().compareTo(BigDecimal.ZERO) == 0) {
            order.setStatus(Constants.OrderStatus.SEND);
        } else {
            order.setStatus(Constants.OrderStatus.NOTPAID);
        }
        order.setAftersaleStatus(1);
        order.setReceiverName(memberAddress.getName());
        order.setReceiverPhone(memberAddress.getPhoneHidden());
        order.setReceiverPhoneEncrypted(memberAddress.getPhoneEncrypted());
        order.setReceiverPostCode(memberAddress.getPostCode());
        order.setReceiverProvince(memberAddress.getProvince());
        order.setReceiverCity(memberAddress.getCity());
        order.setReceiverDistrict(memberAddress.getDistrict());
        order.setReceiverProvinceId(memberAddress.getProvinceId());
        order.setReceiverCityId(memberAddress.getCityId());
        order.setReceiverDistrictId(memberAddress.getDistrictId());
        order.setReceiverDetailAddress(memberAddress.getDetailAddress());
        order.setNote(form.getNote());
        order.setConfirmStatus(0);
        order.setDeleteStatus(0);
//        order.setPaymentTime(optTime);
        order.setCreateTime(optTime);
        order.setCreateBy(member.getId());
        order.setFeeAmount(this.getFeeAmount(order.getPayAmount()));

        
        BigDecimal sysprice =  order.getPayAmount()
        						.subtract(order.getDpjsprice())
        						.subtract(order.getCgprice());
        order.setSysprice(sysprice);//平台结算金额   支付金额-店铺结算金额-供应商结算金额
        
        
        int rows = orderMapper.insert(order);
        if (rows < 1) {
            throw new RuntimeException("订单新增失败");
        }
        // 保存orderItem
        orderItemService.saveOrderItem(member, optTime, orderId, skuList);
        skuList.forEach(item -> {
            //减少sku的库存
            //skuMapper.updateStockById(item.getSkuId(), LocalDateTime.now(), item.getQuantity());
        });
        // 保存订单操作记录
        OrderOperateHistory orderOperateHistory = new OrderOperateHistory();
        orderOperateHistory.setOrderId(orderId);
        orderOperateHistory.setOrderSn(order.getOrderSn());
        orderOperateHistory.setOperateMan(member.getNickname());
        orderOperateHistory.setOrderStatus(Constants.OrderStatus.NOTPAID);
        orderOperateHistory.setCreateTime(optTime);
        orderOperateHistory.setCreateBy(member.getId());
        rows = orderOperateHistoryMapper.insert(orderOperateHistory);
        if (rows < 1) {
            throw new RuntimeException("保存订单操作记录失败");
        }
        //若来源为购物车，删除购物车
//        if (Constants.OrderFrom.CART.equals(form.getFrom())) {
//            List<Long> skuIdList = skuList.stream().map(OrderProductListDTO::getSkuId).collect(Collectors.toList());
//            LambdaUpdateWrapper<MemberCart> wrapper = Wrappers.lambdaUpdate();
//            wrapper.eq(MemberCart::getMemberId, member.getId());
//            wrapper.in(MemberCart::getSkuId, skuIdList);
//            rows = memberCartMapper.delete(wrapper);
//            if (rows < 1) {
//                throw new RuntimeException("删除购物车失败");
//            }
//        }
//        //当前订单id，接入支付后可返回payId
//        //如果是使用了优惠券，更新优惠券状态
//        if (form.getMemberCouponId() != null) {
//            memberCouponService.updateCouponStatus(form.getMemberCouponId(), orderId);
//        }
        String ordercplx = order.getCplx();
        if(ordercplx!=null) {// 1 正常商品 2 福利券商品 3 积分商品
        	if("2".equals(ordercplx) || "3".equals(ordercplx)) {
        		String paramJson = null;
        		if("2".equals(ordercplx)) {//2 福利券商品
        			int num = order.getDhCouponCategoryNum().intValue();
        			List<DyFlqSy> retFlqs = memberCouponService.orderSubmit(order.getId(),num , order.getDhCouponCategoryId(),getdyFqyids(product.getDyCouponCategoryJson()), order.getMemberId()); 
                	if(retFlqs!=null && retFlqs.size()>0) {
                		String flqbz = "福利券使用情况:";
                		for (DyFlqSy flq : retFlqs) {
                			flqbz +=  flq.getName()+"X"+flq.getNum() + "张,";
						}
                		merchantNote = flqbz.substring(0, flqbz.length()-1);
                		Map<String, Object> map = new HashMap<String, Object>();
                		map.put("FLQSY", retFlqs);
                		paramJson = JSONUtil.toJsonStr(map);
                	}
                	if(order.getDhJssl()!=null && !order.getDhJssl().equals(BigDecimal.ZERO)) {
                		memberAccountService.orderSubmit(order.getId(), order.getMemberId(), order.getDhJssl(),productName);
                		merchantNote += "。积分使用情况:兑换商品扣减"+order.getDhJssl()+"积分。";
                	}
        		}
            	if("3".equals(ordercplx)) { // 3 积分商品
       			 	memberAccountService.orderSubmit(order.getId(), order.getMemberId(), order.getDhJssl(),productName);
            		merchantNote = "积分使用情况:兑换商品扣减"+order.getDhJssl()+"积分";

            	}
            	dhSpSuccess(order,merchantNote,paramJson);
        	}
        }
        return payId;
    }
  
    
    
    public Map<String, Object> addOrderCheck(Long memberId,Product product, Sku sku,int stockInt) {
    	 Map<String, Object> retMap = new HashMap<String, Object>();
    	 Long mrxgsLong = product.getMrxgs();//每人限购数量
    	 Long mdxgsLong = product.getMdxgs();//每单限购数量
    	 Long qgsLong = product.getQgs();//起购数量
    	 long mrxgs = 0l;//每人限购数量
    	 long mdxgs = 0l;//每单限购数量
    	 long qgs = 0l;//起购数量
    	 long stock = stockInt;
    	 if(mrxgsLong!=null) { mrxgs = mrxgsLong.longValue();}
    	 if(mdxgsLong!=null) { mdxgs = mdxgsLong.longValue(); }
    	 if(qgsLong!=null) { qgs = qgsLong.longValue();}
    	 
    	 if(mdxgs!= 0l && mdxgs < stock) {
             throw new RuntimeException("此商品每单限购数量为："+mdxgs+"");
    	 }
    	 if(mrxgs!= 0l && mrxgs < stock) {
             throw new RuntimeException("此商品限购数量为："+mrxgs+"");
    	 }
    	 if(qgs!= 0l &&  qgs > stock) {
             throw new RuntimeException("此商品起购数量为："+mdxgs+"");
    	 }
    	 
    	 
    	 if(mrxgs!=0l) {
    		 int ygmsl = orderItemMapper.getOrderProductSumByMid(memberId, product.getId());
        	 if(ygmsl + stock > mrxgs) {
                 throw new RuntimeException("此商品限购数量为："+mrxgs+"");
        	 }  
    	 }
    	 if(product.getCplx()!=null) {// 1 正常商品 2 福利券商品 3 积分商品
    		 if("2".equals(product.getCplx())) { // 2 福利券商品
    			 if(sku.getDhCouponCategoryNum()==null) {
    				 throw new RuntimeException("此商品未设置福利券兑换数量");
    			 }
    			 if(product.getDhCouponCategoryId()==null) {
    				 throw new RuntimeException("此商品未设置福利券兑换类型");
    			 }
    			 int num = sku.getDhCouponCategoryNum().intValue() * stockInt;
    			 List<DyFlqSy> retFlqs =  memberCouponService.checkCoupon(num, product.getDhCouponCategoryId(),getdyFqyids(product.getDyCouponCategoryJson()), memberId); 
    			 if(retFlqs!=null && retFlqs.size()>0) {
        			 retMap.put("flqs", retFlqs);
    			 }
    			 
    			 if(sku.getDhJssl()!=null && !sku.getDhJssl().equals(BigDecimal.ZERO)) {
    				 BigDecimal sumDhJssl = sku.getDhJssl().multiply(BigDecimal.valueOf(stockInt));
        			 memberAccountService.checkJfsl(memberId, sumDhJssl);
    			 }
    		 }
    		 
    		 if("3".equals(product.getCplx())) { // 2 福利券商品
    			 if(sku.getDhJssl()==null) {
    				 throw new RuntimeException("此商品未设置积分兑换数量");
    			 }
    			 BigDecimal sumDhJssl = sku.getDhJssl().multiply(BigDecimal.valueOf(stockInt));
    			 memberAccountService.checkJfsl(memberId, sumDhJssl);
    		 }
    	 }
		return retMap;
    	 
    	 
    	  
    }
    private List<DyFlq> getdyFqyids(String dyCouponCategoryJson) {
    	try {
    		if(dyCouponCategoryJson==null || "".equals(dyCouponCategoryJson)) {
    			return null;
    		}
    		return JSONObject.parseArray(dyCouponCategoryJson, DyFlq.class);
		} catch (Exception e) {
		}
		return null;
    }
    
    
    private String getOrderIdPrefix() {
        LocalDateTime time = LocalDateTime.now();
        return time.format(DateTimeFormatter.ofPattern("yyMMdd")) + "-";
    }
    
    public OrderCalcVO addOrderCheck(OrderCreateForm orderCreateForm,Long memberId) {
        OrderCalcVO res = new OrderCalcVO();
        List<SkuViewVO> skuList = new ArrayList<>();
        List<OrderProductListDTO> list = orderCreateForm.getSkuList();
        if (CollectionUtil.isEmpty(list)) {
            throw new RuntimeException("商品SKU信息不能为空");
        }
        //将购买的sku信息转化为key：skuId value：数量
        Map<Long, Integer> quantityMap = list.stream().
                collect(Collectors.toMap(OrderProductListDTO::getSkuId, OrderProductListDTO::getQuantity, (v1, v2) -> v2));
        //查询所有sku信息
        Set<Long> collect = list.stream().map(OrderProductListDTO::getSkuId).collect(Collectors.toSet());
        Map<Long, Sku> querySkuMap = skuMapper.selectBatchIds(collect).stream().collect(Collectors.toMap(Sku::getId, it -> it));
        //计算商品总金额、订单总金额
        BigDecimal productTotalAmount = BigDecimal.ZERO;
        BigDecimal orderTotalAmount = BigDecimal.ZERO;
        for (OrderProductListDTO dto : list) {
            if (!querySkuMap.containsKey(dto.getSkuId())) {
                throw new RuntimeException("商品SKU不存在");
            }
            Sku sku = querySkuMap.get(dto.getSkuId());
            //查product
            Product product = productMapper.selectById(sku.getProductId());
            if (product == null) {
                throw new RuntimeException("商品不存在");
            }
            if (Constants.PublishStatus.UNDERCARRIAGE.equals(product.getPublishStatus())) {
                throw new RuntimeException("商品" + product.getName() + "已下架");
            }
            if (sku.getStock() < quantityMap.get(sku.getId())) {
                throw new RuntimeException("库存不足");
            }
            Map<String, Object> ocMap = addOrderCheck(memberId, product,sku, dto.getQuantity());
            res.setParams(ocMap);
            BigDecimal addAmount = sku.getPrice().multiply(BigDecimal.valueOf(dto.getQuantity()));
            //由于目前没有运费等数据，暂时订单总金额=商品总金额了
            productTotalAmount = productTotalAmount.add(addAmount);
            orderTotalAmount = orderTotalAmount.add(addAmount);
            //封装sku信息
         
            SkuViewVO skuViewVO = new SkuViewVO();
            skuViewVO.setPic(product.getPic());
            skuViewVO.setPrice(sku.getPrice());
            skuViewVO.setProductId(product.getId());
            skuViewVO.setProductName(product.getName());
            skuViewVO.setQuantity(quantityMap.get(sku.getId()));
            skuViewVO.setSkuId(sku.getId());
            skuViewVO.setSpData(sku.getSpData());


      
            
    		skuViewVO.setCplx(product.getCplx());
    		skuViewVO.setDhCouponCategoryId(product.getDhCouponCategoryId());
    		skuViewVO.setDhCouponCategoryNum(sku.getDhCouponCategoryNum());
    		skuViewVO.setDhJssl(sku.getDhJssl());

            if(product.getCplx()!=null && product.getDhCouponCategoryId()!=null) {
            	CouponCategory couponCategory = couponCategoryService.selectCheckById(product.getDhCouponCategoryId());
            	if(couponCategory!=null) {
            		skuViewVO.setDhCouponCategoryMc(couponCategory.getTitle());
            	}
            }
            skuList.add(skuViewVO);
        }
        res.setSkuList(skuList);
        res.setOrderTotalAmount(orderTotalAmount);
        res.setProductTotalAmount(productTotalAmount);
        //获取能使用的优惠券列表
        Map<Long, Product> products = new HashMap<>();
        querySkuMap.forEach((k, v) -> {
            Integer count = quantityMap.get(k);
            Long productId = v.getProductId();
            Product product;
            BigDecimal amount = v.getPrice().multiply(BigDecimal.valueOf(count));
            if (products.containsKey(k)) {
                product = products.get(k);
                product.setPrice(amount.add(product.getPrice()));
            } else {
                product = new Product();
                product.setId(productId);
                product.setPrice(amount);
            }
            products.put(k, product);
        });
        // res.setCouponList(memberCouponService.getCanUseList(products.values()));
        return res;
    }


//    private String getOrderIdPrefix() {
//        LocalDateTime time = LocalDateTime.now();
//        return time.format(DateTimeFormatter.ofPattern("yyMMdd")) + "-";
//    }

    /**
     * h5订单分页查询
     *
     * @param status   订单状态 -1->全部；0->待付款；1->待发货；2->待收货；-2->售后单
     * @param memberId 会员id
     * @param pageable 分页
     * @return 结果
     */
    public PageImpl<H5OrderVO> orderPage(String lockIdNotIsNull,
    		String lockIdIsNull,Integer sendGysStatus,Integer status, Long memberId,String keyword, Pageable pageable) {
        // 如果全部且页数为1，看看有无待付款单
        List<H5OrderVO> unpaidOrderList = new ArrayList<>();
//        if (Constants.H5OrderStatus.ALL.equals(status) && pageable.getPageNumber() == 0) {
//            unpaidOrderList = orderMapper.orderPage(lockIdNotIsNull,lockIdIsNull,sendGysStatus,Constants.H5OrderStatus.UN_PAY, memberId,keyword);
//        }
        if (pageable != null) {
            PageHelper.startPage(pageable.getPageNumber() + 1, pageable.getPageSize());
        }
        List<H5OrderVO> orderList = orderMapper.orderPage(lockIdNotIsNull,lockIdIsNull,sendGysStatus,status, memberId,keyword);
        long total = ((com.github.pagehelper.Page) orderList).getTotal();
        // 两个list都没数据那肯定返回空了
        if (CollectionUtil.isEmpty(unpaidOrderList) && CollectionUtil.isEmpty(orderList)) {
            return new PageImpl<>(Collections.EMPTY_LIST, pageable, total);
        }
        // 开始组装item了
        // 拿出所有orderId，查item，然后分组 by orderId
        List<Long> idList = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(unpaidOrderList)) {
            idList.addAll(unpaidOrderList.stream().map(H5OrderVO::getOrderId).collect(Collectors.toList()));
        }
        if (CollectionUtil.isNotEmpty(orderList)) {
            idList.addAll(orderList.stream().map(H5OrderVO::getOrderId).collect(Collectors.toList()));
        }
        QueryWrapper<OrderItem> orderItemQw = new QueryWrapper<>();
        orderItemQw.in("order_id", idList);
        Map<Long, List<OrderItem>> orderItemMap =
                orderItemMapper.selectList(orderItemQw).stream().collect(Collectors.groupingBy(OrderItem::getOrderId));
        orderList.addAll(0, unpaidOrderList);
        orderList.forEach(item -> {
            item.setOrderItemList(orderItemMap.get(item.getOrderId()));
            if(item.getCplx()!=null && item.getDhCouponCategoryId()!=null) {
 	        	CouponCategory couponCategory = couponCategoryService.selectCheckById(item.getDhCouponCategoryId());
 	        	if(couponCategory!=null) {
 	        		item.setDhCouponCategoryMc(couponCategory.getTitle());
 	        	}
 	        }
        });
        return new PageImpl<>(orderList, pageable, total);
    }

    public H5OrderVO orderDetail(Long orderId) {
        H5OrderVO order = orderMapper.selectOrderDetail(orderId);
        if (order == null) {
            throw new RuntimeException("未查询到该订单");
        }
        // 组装item
        QueryWrapper<OrderItem> orderItemQw = new QueryWrapper<>();
        orderItemQw.eq("order_id", orderId);
        List<OrderItem> orderItemList = orderItemMapper.selectList(orderItemQw);
        order.setOrderItemList(orderItemList);
        // 如果未付款，计算倒计时
        if (Constants.OrderStatus.NOTPAID.equals(order.getStatus())) {
            // 订单超时时间900s，后面可以配置到字典等
            Integer time = 900;
            Date addDate = Date.from(order.getCreateTime().plusSeconds(time).atZone(ZoneId.systemDefault()).toInstant());
            if (addDate.after(new Date())) {
                order.setTimeToPay(addDate.getTime());
            }
        }
        if(order.getCplx()!=null && order.getDhCouponCategoryId()!=null) {
        	CouponCategory couponCategory = couponCategoryService.selectCheckById(order.getDhCouponCategoryId());
        	if(couponCategory!=null) {
        		order.setDhCouponCategoryMc(couponCategory.getTitle());
        	}
        }
        
        return order;
    }
    
 

    @Transactional
    public void orderCompleteByJob(List<Order> idList) {
        idList.forEach(order -> {
            LocalDateTime optDate = LocalDateTime.now();
            OrderItem queryOrderItem = new OrderItem();
            queryOrderItem.setOrderId(order.getId());
            //更新订单
            order.setStatus(Constants.H5OrderStatus.COMPLETED);
            order.setReceiveTime(optDate);
            order.setConfirmStatus(1);
            order.setUpdateTime(optDate);
            order.setUpdateBy(null);
            
            UpdateWrapper<Order> updateWrapper = new UpdateWrapper<Order>();
            updateWrapper.set("status", order.getStatus());
            updateWrapper.set("receive_time", order.getReceiveTime());
            updateWrapper.set("confirm_status", order.getConfirmStatus());
            updateWrapper.set("update_time", order.getUpdateTime());
            updateWrapper.set("update_by", order.getUpdateBy());
            updateWrapper.eq("id", order.getId());
            int rows = orderMapper.update(null, updateWrapper);
//            orderMapper.updateById(order); 禁止使用
            //创建订单操作记录
            OrderOperateHistory optHistory = new OrderOperateHistory();
            optHistory.setOrderId(order.getId());
            optHistory.setOrderSn(order.getOrderSn());
            optHistory.setOperateMan("后台管理员");
            optHistory.setOrderStatus(Constants.H5OrderStatus.COMPLETED);
            optHistory.setCreateTime(optDate);
            optHistory.setUpdateTime(optDate);
            orderOperateHistoryMapper.insert(optHistory);
        });
    }
  
    
//    @ApiModelProperty("核销人员昵称")
//    private String hxmembernc;
    @Transactional
    public String orderComplete(Long orderId,Long hxmemberid,String hxmembernc) {
        LocalDateTime optDate = LocalDateTime.now();
        Order order = orderMapper.selectById(orderId);
        OrderItem queryOrderItem = new OrderItem();
        queryOrderItem.setOrderId(orderId);
        List<OrderItem> orderItemList = orderItemMapper.selectByEntity(queryOrderItem);
        if (order == null || CollectionUtil.isEmpty(orderItemList)) {
            throw new RuntimeException("未查询到订单信息");
        }
        // 只有【待收货】状态才能确认
//        if (!order.getStatus().equals(Constants.H5OrderStatus.DELIVERED)) {
//            throw new RuntimeException("待收货订单才能收货，状态已改变，请刷新");
//        }
        
//      // 已经核销订单不能重复核销
        if (order.getStatus().equals(Constants.H5OrderStatus.COMPLETED)) {
            throw new RuntimeException("已经核销订单不能重复核销！");
        }
        
        if(order.getLockId() == null) {
        	throw new RuntimeException("订单未锁定不能核销！");
        }
        boolean sfhdjf = false;
        for (OrderItem orderItem : orderItemList) {
        	if(orderItem.getSfhdjf()!=null && orderItem.getSfhdjf().intValue() == 1) {
        		sfhdjf = true;
        	}
            Long pid = orderItem.getProductId();
            if(pid!=null && orderItem.getQuantity()!=null) {
            	Product product = productMapper.selectById(pid);
            	if(product!=null) {
            		
            		Long zsxl = product.getZsxl();
            		if(zsxl==null) {
            			zsxl = 0L;
            		}
            		UpdateWrapper<Product> updateWrapper = new UpdateWrapper<Product>();
            		updateWrapper.set("zsxl", zsxl+orderItem.getQuantity().longValue());
            		updateWrapper.eq("id", pid);
            		productMapper.update(null, updateWrapper);//跟新销量
            	}
            }
		}
        if(sfhdjf) {
        	//处理积分
            integralHistoryService.handleIntegral(order.getId(), order.getPayAmount(), order.getMemberId());
        }
        if(hxmemberid!=null && hxmemberid.longValue() > 0L) {//小于0系统默认用户
        	Member member = (Member) LocalDataUtil.getVar(Constants.MEMBER_INFO);
            Long deptDpId = member.getDeptDpId();
            if(!deptDpId.equals(order.getDeptDpId())) {
                throw new RuntimeException("非自己店铺订单不能确认");
            }
        }
      	

     	
        order.setStatus(Constants.H5OrderStatus.COMPLETED);
        order.setReceiveTime(optDate);
        order.setConfirmStatus(1);
        order.setUpdateTime(optDate);
        order.setHxmemberid(hxmemberid);
        order.setUpdateBy(hxmemberid);
        order.setHxmembernc(hxmembernc);

        UpdateWrapper<Order> updateWrapper = new UpdateWrapper<Order>();
        updateWrapper.set("status", order.getStatus());
        updateWrapper.set("receive_time", order.getReceiveTime());
        updateWrapper.set("confirm_status", order.getConfirmStatus());
        updateWrapper.set("update_time", order.getUpdateTime());
        updateWrapper.set("hxmemberid", order.getHxmemberid());
        updateWrapper.set("hxmembernc", order.getHxmembernc());
        updateWrapper.set("update_by", order.getUpdateBy());
        updateWrapper.eq("id", order.getId());
        int rows = orderMapper.update(null, updateWrapper);
        
//        orderMapper.updateById(order);禁止使用
        //创建订单操作记录
        OrderOperateHistory optHistory = new OrderOperateHistory();
        optHistory.setOrderId(order.getId());
        optHistory.setOrderSn(order.getOrderSn());
        optHistory.setOperateMan(hxmembernc);
        optHistory.setOrderStatus(Constants.H5OrderStatus.COMPLETED);
        optHistory.setCreateTime(optDate);
        optHistory.setCreateBy(hxmemberid);
        optHistory.setUpdateBy(hxmemberid);
        optHistory.setUpdateTime(optDate);
        orderOperateHistoryMapper.insert(optHistory);
        
        
        return order.getOrderSn();
    }

    /**
     * 统计待付款、待发货、待收货和售后订单数量
     *
     * @param memberId
     * @return
     */
    public CountOrderVO orderNumCount(Long memberId) {
        return orderMapper.countByStatusAndMemberId(memberId);
    }
    
    @Transactional
    public String orderCancel(Long orderId, Long userId) {
        LocalDateTime optDate = LocalDateTime.now();
        if (orderId == null) {
            throw new RuntimeException("未指定需要取消的订单号");
        }

        Order orderQxdw = orderMapper.selectById(orderId);
        if (orderQxdw==null) {
            throw new RuntimeException("未查询到订单信息");
        }
        //查orderItem
//        QueryWrapper<OrderItem> qw = new QueryWrapper<>();
//        qw.eq("order_id", orderId);
//        List<OrderItem> orderItem = orderItemMapper.selectList(qw);
//        if (CollectionUtil.isEmpty(orderItem)) {
//            throw new RuntimeException("未查询到订单信息");
//        }
    
        if(!Constants.H5OrderStatus.UN_PAY.equals(orderQxdw.getStatus())){      
            throw new RuntimeException("订单状态更新，请刷新页面重试");
        }
        
        //取消订单
        UpdateWrapper<Order> updateWrapper = new UpdateWrapper<Order>();
        updateWrapper.set("status", Constants.H5OrderStatus.CLOSED);
        updateWrapper.set("update_time", optDate);
        updateWrapper.eq("id", orderId);
        updateWrapper.eq("status", Constants.H5OrderStatus.UN_PAY);
        int rows = orderMapper.update(null, updateWrapper);
        if (rows < 1) {
            throw new RuntimeException("订单状态更新，请刷新页面重试");
        }
//        orderItem.stream().collect(Collectors.groupingBy(it -> it.getSkuId())).forEach((k, v) -> {
//            AtomicReference<Integer> totalCount = new AtomicReference<>(0);
//            v.forEach(it -> totalCount.updateAndGet(v1 -> v1 + it.getQuantity()));
//            //skuMapper.updateStockById(k, optDate, -1 * totalCount.get());
//        });
        //创建订单操作记录
        
        OrderOperateHistory history = new OrderOperateHistory();
        history.setOrderId(orderQxdw.getId());
        history.setOrderSn(orderQxdw.getOrderSn());
        history.setOperateMan(userId == null ? "后台管理员" : "" + orderQxdw.getMemberId());
        history.setOrderStatus(Constants.H5OrderStatus.CLOSED);
        history.setCreateTime(optDate);
        history.setCreateBy(userId);
        history.setUpdateBy(userId);
        history.setUpdateTime(optDate);
        boolean flag = orderOperateHistoryService.save(history);
        if (!flag) {
            throw new RuntimeException("创建订单操作记录失败");
        }
        return "取消订单成功";
    }
    
    

    @Transactional
    public String orderBatchCancel(List<Order> orderList, List<Long> idList) {
        LocalDateTime optDate = LocalDateTime.now();
         Long userId = null;
        //查orderItem
        QueryWrapper<OrderItem> qw = new QueryWrapper<>();
        qw.in("order_id", idList);
        List<OrderItem> orderItem = orderItemMapper.selectList(qw);
        if (CollectionUtil.isEmpty(orderItem)) {
            throw new RuntimeException("未查询到订单信息");
        }
        long count = orderList.stream().filter(it -> !Constants.H5OrderStatus.UN_PAY.equals(it.getStatus())).count();
        if (count > 0) {
            throw new RuntimeException("订单状态已更新，请刷新页面");
        }
        List<OrderOperateHistory> addHistoryList = new ArrayList<>();
        orderList.forEach(item -> {
            item.setStatus(Constants.H5OrderStatus.CLOSED);
            item.setUpdateTime(optDate);
            item.setUpdateBy(userId);
            OrderOperateHistory history = new OrderOperateHistory();
            history.setOrderId(item.getId());
            history.setOrderSn(item.getOrderSn());
            history.setOperateMan(userId == null ? "后台管理员" : "" + item.getMemberId());
            history.setOrderStatus(Constants.H5OrderStatus.CLOSED);
            history.setCreateTime(optDate);
            history.setCreateBy(userId);
            history.setUpdateBy(userId);
            history.setUpdateTime(optDate);
            addHistoryList.add(history);

        });
        //取消订单
        UpdateWrapper<Order> updateWrapper = new UpdateWrapper<Order>();
        updateWrapper.set("status", Constants.H5OrderStatus.CLOSED);
        updateWrapper.set("update_time", optDate);
        updateWrapper.in("id", idList);
        updateWrapper.eq("status", Constants.OrderStatus.NOTPAID);
        updateWrapper.eq("aftersale_status", 1);
        int rows = orderMapper.update(null, updateWrapper);
//        int rows = orderMapper.cancelBatch(orderList);
        if (rows < 1) {
            throw new RuntimeException("更改订单状态失败");
        }
        orderItem.stream().collect(Collectors.groupingBy(it -> it.getSkuId())).forEach((k, v) -> {
            AtomicReference<Integer> totalCount = new AtomicReference<>(0);
            v.forEach(it -> totalCount.updateAndGet(v1 -> v1 + it.getQuantity()));
            //skuMapper.updateStockById(k, optDate, -1 * totalCount.get());
        });

        //创建订单操作记录
        boolean flag = orderOperateHistoryService.saveBatch(addHistoryList);
        if (!flag) {
            throw new RuntimeException("创建订单操作记录失败");
        }
        //判断是否使用优惠券，有的话，把优惠券还回去
        List<Long> couponIdList = orderList.stream().filter(it -> it.getMemberCouponId() != null).map(Order::getMemberCouponId).collect(Collectors.toList());
        if (!CollectionUtils.isEmpty(couponIdList)) {
            memberCouponService.backCoupon(couponIdList);
        }
        return "取消订单成功";
    }
 
    /**
     * 订单支付
     *
     * @param req 支付请求
     * @return
     */
    public OrderPayVO orderPay(OrderPayForm req) {
        QueryWrapper<Order> qw = new QueryWrapper<>();
        qw.eq("pay_id", req.getPayId());
        qw.eq("status", Constants.H5OrderStatus.UN_PAY);
        List<Order> orderList = orderMapper.selectList(qw);
        if (CollectionUtil.isEmpty(orderList)) {
            throw new RuntimeException("没有待支付的订单");
        }
        Member member = (Member) LocalDataUtil.getVar(Constants.MEMBER_INFO);
        if (member == null) {
            throw new RuntimeException("获取用户openId失败");
        }
        Order sbOrder = orderList.get(0);
        String orderDesc = "";
        for (Order order : orderList) {
        	
        	orderDesc = order.getKeyword();
        	try {
        		orderDesc = orderDesc.split("订单id")[0].replaceAll("\\{", "").replaceAll("}", "").replace("\"", "");
			} catch (Exception e) {
				 
			}
        	if (Duration.between(order.getCreateTime(), LocalDateTime.now()).toMinutes() >= 15L) {
        		try {
        			orderCancel(order.getId(), null);
				} catch (Exception e) {
					 e.printStackTrace();
				}
        	    throw new RuntimeException("订单超过15分钟未支付，已自动取消。");
        	} 
		}
        
        String openId = member.getOpenid();
        QueryWrapper<OrderItem> orderItemQw = new QueryWrapper<>();
        orderItemQw.eq("order_id", orderList.get(0).getId());
        orderDesc = orderDesc.substring(0, Math.min(40, orderDesc.length()));
        //保存微信支付历史
        LocalDateTime optDate = LocalDateTime.now();
        QueryWrapper<WechatPaymentHistory> wxPaymentQw = new QueryWrapper<>();
        wxPaymentQw.eq("order_id", orderList.get(0).getPayId());
        wxPaymentQw.eq("op_type", Constants.PaymentOpType.PAY);
        WechatPaymentHistory wechatPaymentHistory = wechatPaymentHistoryMapper.selectOne(wxPaymentQw);
        SysDept sysDept = deptService.getCacheSysDept(member.getDeptDpId());
        OrderPayVO orderPayVO = yeePayService.satrOrderPay(member,  orderList.get(0), orderDesc, sysDept);
        if (wechatPaymentHistory == null) {
            wechatPaymentHistory = new WechatPaymentHistory();
            wechatPaymentHistory.setOrderId(orderList.get(0).getPayId());
            wechatPaymentHistory.setMemberId(req.getMemberId());
            wechatPaymentHistory.setOpenid(openId);
            wechatPaymentHistory.setTitle(orderDesc);
            wechatPaymentHistory.setMoney(orderList.get(0).getPayAmount());
            wechatPaymentHistory.setOpType(Constants.PaymentOpType.PAY);
            wechatPaymentHistory.setPaymentStatus(0);
            wechatPaymentHistory.setCreateBy(req.getMemberId());
            wechatPaymentHistory.setCreateTime(optDate);
            wechatPaymentHistory.setUpdateBy(req.getMemberId());
            wechatPaymentHistory.setUpdateTime(optDate);
            wechatPaymentHistory.setBankOrderId(orderPayVO.getBankOrderId()); 
            wechatPaymentHistory.setUniqueOrderNo(orderPayVO.getUniqueOrderNo());
            wechatPaymentHistory.setZbjlid(req.getZbjlid()); 
            wechatPaymentHistory.setDeptZbjId(sbOrder.getDeptZbjId());
            wechatPaymentHistory.setDeptTzId(sbOrder.getDeptTzId());
            wechatPaymentHistory.setDeptDpId(sbOrder.getDeptDpId());
            
            wechatPaymentHistory.setResponseBody(orderPayVO.getResponseBody());
            wechatPaymentHistoryMapper.insert(wechatPaymentHistory);
        } else {
            UpdateWrapper<WechatPaymentHistory> updateWrapper = new UpdateWrapper<>();
            updateWrapper.eq("id", wechatPaymentHistory.getId())
            		.set("money", orderList.get(0).getPayAmount())
            		.set("bank_order_id", orderPayVO.getBankOrderId())
            		.set("unique_order_no", orderPayVO.getUniqueOrderNo())
                    .set("response_body", orderPayVO.getResponseBody())
                    .set("update_time", optDate);
            wechatPaymentHistoryMapper.update(null, updateWrapper);
        }
        return orderPayVO;
    }

    /**
     * 	兑换商品成功
     *
     * @param messageDTO
     * @return
     */
    public void dhSpSuccess(Order order,String merchantNote,String paramJson) {
    	LocalDateTime thisDateTime = LocalDateTime.now();
        UpdateWrapper<Order> updateWrapper = new UpdateWrapper<Order>();
        Integer IntProcess =  order.getProcess();
        int proces = 0;
        Long orderId = null;
        if(IntProcess !=null) {	// 订单流程：0正常流程  1支付就待提货    2支付后无需核销直接完成
        	 proces = IntProcess.intValue();
        	if(proces==1 || proces==2) {
                long lockId = Long.parseLong((proces+1)+DateUtil.format(DateUtil.date(), "yyyyMMdd")+ order.getDeptZbjId());
        		order.setLockId(lockId);
                updateWrapper.set("lock_id", order.getLockId());
        	}
        }
        
        updateWrapper.set("param_json", paramJson);
        updateWrapper.set("merchant_note", merchantNote);
        updateWrapper.set("payment_time", thisDateTime);
        updateWrapper.set("status", OrderStatus.NOT_DELIVERED.getType());
        updateWrapper.set("merchantno", yeePayService.getBaseMerchantNoH5(order.getDeptZbjId()));
        updateWrapper.eq("id", order.getId());
        orderMapper.update(null, updateWrapper);

        OrderOperateHistory optHistory = new OrderOperateHistory();
        optHistory.setOrderId(order.getId());
        optHistory.setOrderSn(order.getOrderSn());
        optHistory.setOperateMan("" + order.getMemberId());
        optHistory.setOrderStatus(OrderStatus.NOT_DELIVERED.getType());
        optHistory.setCreateTime(thisDateTime);
        optHistory.setCreateBy(order.getMemberId());
        optHistory.setUpdateBy(order.getMemberId());
        optHistory.setUpdateTime(thisDateTime);
        optHistory.setNote("兑换成功");
        orderOperateHistoryMapper.insert(optHistory);
        orderId = order.getId();
        if(proces==2 && orderId!=null) {
        	try {
        		orderComplete(orderId, -10l, "支付后直接完成, 系统自动核销");
			} catch (Exception e) {
				   log.error("支付后直接完成, 系统自动核销调用异常：", e);
			}
    	}
       
    }

    
    
    /**
     * 支付回调方法
     *
     * @param messageDTO
     * @return
     */
    @Transactional
    public boolean yeePayCallBack(PayNotifyRetVo pyNotifyRetVo,String response_body) {
    	log.info("【订单支付回调】" + JSONObject.toJSON(pyNotifyRetVo));
        String redisKey = "h5_oms_order_pay_notify_" + pyNotifyRetVo.getOrderId();
        String redisValue = pyNotifyRetVo.getOrderId() + "_" + System.currentTimeMillis();
        LocalDateTime optDate = LocalDateTime.now();
        try {
            redisService.lock(redisKey, redisValue, 60);
            //先判断回信回调的是否未success
            if (!"SUCCESS".equals(pyNotifyRetVo.getStatus())) {
                log.error("【订单支付回调】订单状态不是支付成功状态" + pyNotifyRetVo.getStatus());
                throw new RuntimeException("订单支付回调 订单状态不是支付成功状态");
            }
            
            
            QueryWrapper<Order> orderQw = new QueryWrapper<>();
            orderQw.eq("pay_id", pyNotifyRetVo.getOrderId());
            orderQw.in("status", OrderStatus.UN_PAY.getType(),OrderStatus.CLOSED.getType());//订单关闭或者没有支付
            List<Order> orderList = orderMapper.selectList(orderQw);
            if(orderList==null || orderList.size()==0) {
            	   QueryWrapper<Order> queryWrapper = new QueryWrapper<>();
            	   queryWrapper.eq("pay_id", pyNotifyRetVo.getOrderId());
                   List<Order> listOrder = orderMapper.selectList(queryWrapper);
                   if(listOrder!=null && listOrder.size()>0) {
                	   	if(listOrder.get(0).getPaymentTime()!=null) {
                	   		return true;//订单已经支付成功了直接返回成功
                	   	}
                   }
            	  throw new RuntimeException("【订单支付回调】没有带支付的订单，UN_PAY OR CLOSED" );
            }
            
            QueryWrapper<WechatPaymentHistory> paymentWrapper = new QueryWrapper<>();
            paymentWrapper.eq("order_id", pyNotifyRetVo.getOrderId());
            paymentWrapper.eq("op_type", Constants.PaymentOpType.PAY);
            WechatPaymentHistory paymentHistory = wechatPaymentHistoryMapper.selectOne(paymentWrapper);
            if(paymentHistory==null) {
                throw new RuntimeException("【订单支付回调】paymentHistory is null" );
            }
            if (paymentHistory.getPaymentStatus() != Constants.PaymentStatus.INCOMPLETE) {
                log.info("【订单支付回调】支付订单不是未支付状态，不再处理" + "orderId" + paymentHistory.getOrderId() + "status" + paymentHistory.getPaymentStatus());
                throw new RuntimeException("【订单支付回调】支付订单不是未支付状态，不再处理" );
            }
            
//            LocalDateTime paymentTime = DateUtil.parseLocalDateTime(pyNotifyRetVo.getPaySuccessDate());
            LocalDateTime paymentTime = optDate;
           
            orderList.forEach(order -> {
            	
            	if(order.getStatus() == OrderStatus.CLOSED.getType()) {
            		if(order.getAftersaleTime()!=null || order.getAftersaleStatus().intValue() != 1) {
                        throw new RuntimeException("【订单支付回调】已经发起退款，不再处理" );
            		}
            	}
            	 
                UpdateWrapper<Order> updateWrapper = new UpdateWrapper<Order>();
                order.setPaymentTime(paymentTime);
                order.setStatus(OrderStatus.NOT_DELIVERED.getType());
                order.setMerchantno(pyNotifyRetVo.getMerchantNo());
                order.setUniqueorderno(pyNotifyRetVo.getUniqueOrderNo());
                Integer IntProcess =  order.getProcess();
                
              
                int proces = 0;
                Long orderId = null;
                if(IntProcess !=null) {	// 订单流程：0正常流程  1支付就待提货    2支付后无需核销直接完成
                	 proces = IntProcess.intValue();
                	if(proces==1 || proces==2) {
                        long lockId = Long.parseLong((proces+1)+DateUtil.format(DateUtil.date(), "yyyyMMdd")+ order.getDeptZbjId());
                		order.setLockId(lockId);
                        updateWrapper.set("lock_id", order.getLockId());
                	}
                	
                }
                
                updateWrapper.set("payment_time", order.getPaymentTime());
                updateWrapper.set("status", order.getStatus());
                updateWrapper.set("merchantno", order.getMerchantno());
                updateWrapper.set("uniqueorderno", order.getUniqueorderno());
                updateWrapper.eq("id", order.getId());
                int rows = orderMapper.update(null, updateWrapper);
                
//                orderMapper.updateById(order);禁止使用

                OrderOperateHistory optHistory = new OrderOperateHistory();
                optHistory.setOrderId(order.getId());
                optHistory.setOrderSn(order.getOrderSn());
                optHistory.setOperateMan("" + order.getMemberId());
                optHistory.setOrderStatus(order.getStatus());
                optHistory.setCreateTime(optDate);
                optHistory.setCreateBy(order.getMemberId());
                optHistory.setUpdateBy(order.getMemberId());
                optHistory.setUpdateTime(optDate);
                orderOperateHistoryMapper.insert(optHistory);
                orderId = order.getId();
                
                if(proces==2 && orderId!=null) {
                	try {
                		orderComplete(orderId, -10l, "支付后直接完成, 系统自动核销");
					} catch (Exception e) {
						   log.error("支付后直接完成, 系统自动核销调用异常：", e);
					}
            	}
            });
            UpdateWrapper<WechatPaymentHistory> paymentHistoryUpdateWrapper = new UpdateWrapper<>();
            paymentHistoryUpdateWrapper
            						.eq("order_id", pyNotifyRetVo.getOrderId())
            						.set("payment_id", pyNotifyRetVo.getUniqueOrderNo())
            						.set("payment_status", Constants.PaymentStatus.COMPLETE)
            	            		.set("response_back_body", response_body)
            						.set("update_time", optDate);
            wechatPaymentHistoryMapper.update(null, paymentHistoryUpdateWrapper);
            return true;
        } catch (Exception e) {
            log.error("订单支付回调异常", e);
            return false;
            //throw new RuntimeException("订单支付回调异常"+e.getMessage());
        } finally {
            try {
                redisService.unLock(redisKey, redisValue);
            } catch (Exception e) {
                log.error("", e);
            }
        }
        
       
    }

    
    
    
//    /**
//     * 支付回调方法
//     *
//     * @param messageDTO
//     * @return
//     */
//    @Transactional
//    public ResponseEntity<String> payCallBack(PayNotifyMessageDTO messageDTO) {
//        log.info("【订单支付回调】" + JSONObject.toJSON(messageDTO));
//        String redisKey = "h5_oms_order_pay_notify_" + messageDTO.getOutTradeNo();
//        String redisValue = messageDTO.getOutTradeNo() + "_" + System.currentTimeMillis();
//        LocalDateTime optDate = LocalDateTime.now();
//        try {
//            redisService.lock(redisKey, redisValue, 60);
//            //先判断回信回调的是否未success
//            if (!Transaction.TradeStateEnum.SUCCESS.equals(messageDTO.getTradeStatus())) {
//                log.error("【订单支付回调】订单状态不是支付成功状态" + messageDTO.getTradeStatus());
//                throw new RuntimeException();
//            }
//            QueryWrapper<WechatPaymentHistory> paymentWrapper = new QueryWrapper<>();
//            paymentWrapper.eq("order_id", messageDTO.getOutTradeNo());
//            paymentWrapper.eq("op_type", Constants.PaymentOpType.PAY);
//            WechatPaymentHistory paymentHistory = wechatPaymentHistoryMapper.selectOne(paymentWrapper);
//            if (paymentHistory.getPaymentStatus() != Constants.PaymentStatus.INCOMPLETE) {
//                log.info("【订单支付回调】支付订单不是未支付状态，不再处理" + "orderId" + paymentHistory.getOrderId() + "status" + paymentHistory.getPaymentStatus());
//                throw new RuntimeException();
//            }
//            QueryWrapper<Order> orderQw = new QueryWrapper<>();
//            orderQw.eq("pay_id", messageDTO.getOutTradeNo());
//            orderQw.eq("status", OrderStatus.UN_PAY.getType());
//            List<Order> orderList = orderMapper.selectList(orderQw);
//            orderList.forEach(order -> {
//                UpdateWrapper<Order> updateWrapper = new UpdateWrapper<Order>();
//                order.setPaymentTime(messageDTO.getPayTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime());
//                order.setStatus(OrderStatus.NOT_DELIVERED.getType());
//               Integer IntProcess =  order.getProcess();
//                if(IntProcess !=null) {	// 订单流程：0正常流程  1支付就待提货
//                	int proces = IntProcess.intValue();
//                	if(proces==1) {
//                        long lockTime = Long.parseLong("2"+DateUtil.format(DateUtil.date(), "yyyyMMddHHssSSS")+ order.getMemberId());
//                		order.setLockId(lockTime);
//                        updateWrapper.set("lock_id", order.getLockId());
//
//                	}
//                }
//                
//                updateWrapper.set("payment_time", order.getReceiveTime());
//                updateWrapper.set("status", order.getStatus());
//                updateWrapper.eq("id", order.getId());
//                int rows = orderMapper.update(null, updateWrapper);
//                
//                
////                orderMapper.updateById(order);禁止使用
//
//                OrderOperateHistory optHistory = new OrderOperateHistory();
//                optHistory.setOrderId(order.getId());
//                optHistory.setOrderSn(order.getOrderSn());
//                optHistory.setOperateMan("" + order.getMemberId());
//                optHistory.setOrderStatus(OrderStatus.NOT_DELIVERED.getType());
//                optHistory.setCreateTime(optDate);
//                optHistory.setCreateBy(order.getMemberId());
//                optHistory.setUpdateBy(order.getMemberId());
//                optHistory.setUpdateTime(optDate);
//                orderOperateHistoryMapper.insert(optHistory);
//
//            
//            });
//            UpdateWrapper<WechatPaymentHistory> paymentHistoryUpdateWrapper = new UpdateWrapper<>();
//            paymentHistoryUpdateWrapper.eq("order_id", messageDTO.getOutTradeNo()).set("payment_id", messageDTO.getTradeNo())
//                    .set("payment_status", Constants.PaymentStatus.COMPLETE).set("update_time", optDate);
//            wechatPaymentHistoryMapper.update(null, paymentHistoryUpdateWrapper);
//        } catch (Exception e) {
//            log.error("订单支付回调异常", e);
//            throw new RuntimeException("订单支付回调异常"+e.getMessage());
//        } finally {
//            try {
//                redisService.unLock(redisKey, redisValue);
//            } catch (Exception e) {
//                log.error("", e);
//            }
//        }
//        return ResponseEntity.ok("订单支付回调成功");
//    }

    /**
     * 申请售后
     *sfqz是否强制退款
     * @param applyRefundForm
     * @return
     */
    @Transactional
    public Order applyRefund(ApplyRefundForm applyRefundForm,boolean sfqz) {
        Order order = orderMapper.selectById(applyRefundForm.getOrderId());
        //是否符合售后条件
        this.checkIfCanApplyRefund(order,sfqz);
        LocalDateTime optDate = LocalDateTime.now();
        Long memberId = order.getMemberId();
        //创建售后单aftersale
        Aftersale addAftersale = new Aftersale();
        addAftersale.setId(IDGenerator.generateId());
        addAftersale.setMemberId(order.getMemberId());
        addAftersale.setOrderId(order.getId());
        addAftersale.setReturnAmount(order.getPayAmount());
        addAftersale.setType(applyRefundForm.getApplyRefundType());
        addAftersale.setStatus(AftersaleStatus.APPLY.getType());
        addAftersale.setReason(applyRefundForm.getReason());
        addAftersale.setQuantity(applyRefundForm.getQuantity());
        addAftersale.setReason(applyRefundForm.getReason());
        addAftersale.setDescription(applyRefundForm.getDescription());
        addAftersale.setProofPics(applyRefundForm.getProofPics());
        addAftersale.setCreateTime(optDate);
        addAftersale.setCreateBy(memberId);
        addAftersale.setUpdateTime(optDate);
        addAftersale.setUpdateBy(memberId);
        
        addAftersale.setDeptDpId(order.getDeptDpId());
        addAftersale.setDeptTzId(order.getDeptTzId());
        addAftersale.setDeptZbjId(order.getDeptZbjId());
        addAftersale.setSpreaduid(order.getSpreaduid());

        int rows = aftersaleMapper.insert(addAftersale);
        if (rows != 1) {
            throw new RuntimeException("插入订单售后失败");
        }
        //创建aftersale item
        QueryWrapper<OrderItem> orderItemQw = new QueryWrapper<>();
        orderItemQw.eq("order_id", order.getId());
        List<OrderItem> orderItemList = orderItemMapper.selectList(orderItemQw);
        List<AftersaleItem> addAftersaleItemList = new ArrayList<>();
        orderItemList.forEach(orderItem -> {
            AftersaleItem aftersaleItem = new AftersaleItem();
            aftersaleItem.setMemberId(memberId);
            aftersaleItem.setAftersaleId(addAftersale.getId());
            aftersaleItem.setOrderId(orderItem.getOrderId());
            aftersaleItem.setOrderItemId(orderItem.getId());
            aftersaleItem.setReturnAmount(orderItem.getSalePrice().multiply(BigDecimal.valueOf(orderItem.getQuantity())));
            aftersaleItem.setQuantity(orderItem.getQuantity());
            aftersaleItem.setCreateTime(optDate);
            aftersaleItem.setCreateBy(memberId);
            aftersaleItem.setUpdateTime(optDate);
            aftersaleItem.setUpdateBy(memberId);
            addAftersaleItemList.add(aftersaleItem);
        });
        rows = aftersaleItemMapper.insertBatch(addAftersaleItemList);
        if (rows < 1) {
            throw new RuntimeException("创建售后订单item失败");
        }
        //更新订单
        UpdateWrapper<Order> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("id", order.getId()).set("aftersale_status", OrderRefundStatus.APPLY.getType())
                .set("update_time", optDate)
                .set("update_by", memberId);
        rows = orderMapper.update(null, updateWrapper);
        if (rows < 1) {
            throw new RuntimeException("修改订单状态失败");
        }
        //创建订单操作记录
        OrderOperateHistory optHistory = new OrderOperateHistory();
        optHistory.setOrderId(order.getId());
        optHistory.setOrderSn(order.getOrderSn());
        optHistory.setOperateMan("" + memberId);
        optHistory.setOrderStatus(11);
        optHistory.setCreateTime(optDate); 
        optHistory.setCreateBy(memberId);
        optHistory.setUpdateBy(memberId);
        optHistory.setUpdateTime(optDate);
        rows = orderOperateHistoryMapper.insert(optHistory);
        if (rows < 1) {
            throw new RuntimeException("创建订单操作记录失败");
        }
        return order;
    }
	
	/**
     * check是否能售后 可售后的状态为：待发货、待收货、已完成
     * sfqz 是否强制
     * @param order 订单
     */
    private void checkIfCanApplyRefund(Order order,boolean sfqz) {
        if (order == null) {
            throw new RuntimeException("为查询到订单信息");
        }
        if(sfqz == false) {//用户自己退款
        	 Integer status = order.getStatus();
             boolean flag = OrderStatus.NOT_DELIVERED.getType().equals(status) || OrderStatus.DELIVERED.getType().equals(status)
                     || OrderStatus.COMPLETE.getType().equals(status);
             
             if (!OrderStatus.NOT_DELIVERED.getType().equals(status)) {
                 throw new RuntimeException("该订单无法申请售后");
             }
             if(order.getKtkTime()!=null) {
            	 if(order.getKtkTime().isBefore(LocalDateTime.now()) ) {
                	 throw new RuntimeException("已过退款时间,请联系店长");
            	 }
             }
             Long lockId = order.getLockId();
             if (lockId != null) {
                 throw new RuntimeException("该订单已锁定无法申请售后,请联系店长");
             }
            

        }
        
        
     
        
        
        String ordercplx = order.getCplx();
        if(ordercplx!=null) {// 1 正常商品 2 福利券商品 3 积分商品
    		if("2".equals(ordercplx)) {//2 福利券商品
    			 	throw new RuntimeException("福利券兑换商品暂不支持，退货！");
        	}
        	if("3".equals(ordercplx)) { //3 积分商品
   			 		throw new RuntimeException("积分兑换商品暂不支持，退货！");
        	}
        }
        
        if (order.getAftersaleTime() != null) {
            throw new RuntimeException("已退款到账可能延迟，请勿重试操作！");
        }
        
        
        if (order.getPaymentTime() == null) {
            throw new RuntimeException("未付款订单无需申请售后");
        }
        
        if (OrderStatus.COMPLETE.getType().equals(order.getStatus()) &&
                DateUtils.betweenDay(LocalDateTime.now(), order.getReceiveTime()) > 30) {
            throw new RuntimeException("订单确认收货时间已超过30天，无法申请售后");
        }
        
        if (OrderRefundStatus.APPLY.getType().equals(order.getAftersaleStatus())
                || OrderRefundStatus.WAIT.getType().equals(order.getAftersaleStatus())) {
            throw new RuntimeException("售后正在处理中");
        }
    }

    /**
     * 取消售后
     *
     * @param orderId 订单id
     * @return
     */
    @Transactional
    public String cancelRefund(Long orderId) {
        Order order = orderMapper.selectById(orderId);
        if (order == null) {
            throw new RuntimeException("未查询到该订单");
        }
        //查询是否有（待处理和退货中）售后单
        QueryWrapper<Aftersale> aftersaleQw = new QueryWrapper<>();
        aftersaleQw.eq("order_id", orderId);
        aftersaleQw.in("status", Arrays.asList(AftersaleStatus.APPLY.getType(), AftersaleStatus.WAIT.getType()));
        Aftersale aftersale = aftersaleMapper.selectOne(aftersaleQw);
        if (aftersale == null) {
            throw new RuntimeException("无售后单");
        }
        if (OrderRefundStatus.SUCCESS.getType().equals(order.getAftersaleStatus())) {
            throw new RuntimeException("已退款成功");
        }
        Member member = (Member) LocalDataUtil.getVar(Constants.MEMBER_INFO);
        LocalDateTime optDate = LocalDateTime.now();
        //更新售后单状态
        UpdateWrapper<Aftersale> aftersaleUpdateWrapper = new UpdateWrapper<>();
        aftersaleUpdateWrapper.eq("id", aftersale.getId());
        aftersaleUpdateWrapper.set("status", AftersaleStatus.CANCEL.getType());
        aftersaleUpdateWrapper.set("update_time", optDate);
        aftersaleUpdateWrapper.set("update_by", member.getId());
        int rows = aftersaleMapper.update(null, aftersaleUpdateWrapper);
        if (rows < 1) {
            throw new RuntimeException("更新售后单失败");
        }
        //更新订单售后状态
        // 更新订单
        UpdateWrapper<Order> updateOrderWrapper = new UpdateWrapper<>();
        updateOrderWrapper.eq("id", orderId)
                .set("aftersale_status", OrderRefundStatus.NO_REFUND.getType()).set("update_time", optDate)
                .set("update_by", member.getId());
        rows = orderMapper.update(null, updateOrderWrapper);
        if (rows != 1) {
            throw new RuntimeException("更新订单状态失败");
        }
        return "售后取消成功";
    }

    /**
     * 售后订单详情
     *
     * @param orderId 订单id
     * @return
     */
    public AftersaleRefundInfoVO refundOrderDetail(Long orderId) {
        QueryWrapper<Aftersale> aftersaleQw = new QueryWrapper<>();
        aftersaleQw.eq("order_id", orderId);
        aftersaleQw.orderByDesc("create_time");
        aftersaleQw.last("limit 1");
        Aftersale aftersale = aftersaleMapper.selectOne(aftersaleQw);
        if (aftersale == null) {
            throw new RuntimeException("未查询到售后订单");
        }
        //查一下售后订单item
        QueryWrapper<AftersaleItem> aftersaleItemQw = new QueryWrapper<>();
        aftersaleItemQw.eq("aftersale_id", aftersale.getId());
        List<AftersaleItem> aftersaleItemList = aftersaleItemMapper.selectList(aftersaleItemQw);
        List<Long> orderItemIdList = aftersaleItemList.stream().map(AftersaleItem::getOrderItemId).collect(Collectors.toList());
        //再去查orderItem
        QueryWrapper<OrderItem> orderItemQw = new QueryWrapper<>();
        orderItemQw.in("id", orderItemIdList);
        List<OrderItem> orderItemList = orderItemMapper.selectList(orderItemQw);
        AftersaleRefundInfoVO vo = new AftersaleRefundInfoVO();
        BeanUtils.copyProperties(aftersale, vo);
        vo.setAftersaleItemList(aftersaleItemConvert.dos2vos(aftersaleItemList));
        vo.setOrderItemList(orderItemConvert.dos2vos(orderItemList));
        return vo;
    }

    public Order selectById(Long orderId) {
        return orderMapper.selectById(orderId);
    }


    /**
     * 	统计支付未退款的店铺订单
     * @param query
     * @param page
     * @return
     */
    public List<ManagerOrderVO> selectShopHxProductTj(ManagerOrderQueryForm query) {
    	if(query.getDeptDpId() == null) {
            throw new RuntimeException("店铺id不能为空");
    	}
    	
    	if(query.getPayStartTime() == null && query.getRecStartTime()==null) {
            throw new RuntimeException("支付时间和核销时间二选一");
    	} 
    	if(query.getPayStartTime() != null) {
    		if(Duration.between(query.getPayStartTime(), query.getPayEndTime()).toDays() > 30) {
    			throw new RuntimeException("最多只能查询30天的数据");
    		}
    	}
    
    	if(query.getRecStartTime() !=  null) {
	    	if(Duration.between(query.getRecStartTime(), query.getRecEndTime()).toDays() > 30) {
				throw new RuntimeException("最多只能查询30天的数据");
	    	}
    	}
    	return orderMapper.selectShopHxProductTj(query);
    }
    
 
}
